package com.group9.handinhand.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.group9.handinhand.dao.CommunityDao;
import com.group9.handinhand.dao.EventDao;
import com.group9.handinhand.dao.UserDao;
import com.group9.handinhand.dao.model.Community;
import com.group9.handinhand.dao.model.Event;
import com.group9.handinhand.dao.model.EventAttender;
import com.group9.handinhand.dao.model.EventPost;
import com.group9.handinhand.dao.model.User;
import com.group9.handinhand.service.so.ActivityEnums.ActivityType;
import com.group9.handinhand.service.so.CommunitySO;
import com.group9.handinhand.service.so.EventAttenderSO;
import com.group9.handinhand.service.so.EventPostSO;
import com.group9.handinhand.service.so.EventSO;
import com.group9.handinhand.service.so.UserSO;
import com.group9.handinhand.service.so.UserTagSO;

@Transactional
@Service("eventService")
public class EventServiceImpl implements EventService {
	
	@Autowired
	EventDao eventDao;
	
	@Autowired
	CommunityDao communityDao;
	
	@Autowired
	UserDao userDao;
	/**
	 * Saves event with user, community id and event
	 * @param so
	 * @param user
	 * @param communityId
	 */
	@Override
	public EventSO saveEvent(EventSO so, UserSO user, Long communityId) {
		so.setActivityType(ActivityType.NONE);
		
		Community community = communityDao.findCommunityById(communityId);
		CommunitySO communitySO = community.convertToServiceObject();
		so.getModerators().addAll(communitySO.getModerators());
		
		boolean userModerator = false;
		for (UserSO moderator : communitySO.getModerators()) {
			 if(moderator.equals(user)) {
				 userModerator = true;
			 }
		}
		if(!userModerator)
			so.getModerators().add(user);
		
		Event model = so.convertToModelObject();
		model.setCommunity(community);
		
		model.setCreator(userDao.findUserById(user.getId()));
		
		model = eventDao.saveEvent(model);
		if(model != null) {
			saveEventAttender(model.getId(), user.getId());
			return model.convertToServiceObject();
		}
		return null;
	}
	/**
	 * Gets the events with tag
	 * @param tag
	 * @return list of the events
	 */
	@Override
	public List<EventSO> getEventsByTag(UserTagSO tag) {
		List<Event> modelList = eventDao.findEventsByTag(tag);
		List<EventSO> soList = new ArrayList<EventSO>();
		for (Event model : modelList) {
			soList.add(model.convertToServiceObject());
		}
		return soList;
	}
	/**
	 * Gets the events with tag name.
	 * @param name of the tag
	 * @ return list of the events
	 */
	@Override
	public List<EventSO> getEventsByTagName(String keyword) {
		List<Event> modelList = eventDao.findEventsByTagName(keyword);
		List<EventSO> soList = new ArrayList<EventSO>();
		for (Event model : modelList) {
			soList.add(model.convertToServiceObject());
		}
		return soList;
	}
	/**
	 * Gets the events with name.
	 * @param event name
	 * @return the list of the events with specific name
	 */
	@Override
	public List<EventSO> getEventsByName(String keyword) {
		List<Event> modelList = eventDao.findEventsByName(keyword);
		List<EventSO> soList = new ArrayList<EventSO>();
		for (Event model : modelList) {
			soList.add(model.convertToServiceObject());
		}
		return soList;
	}
	/**
	 * Gets the events list with community id
	 * @param communityId
	 * @return the list of events
	 */
	public List<EventSO> getEventsByCommunityId(Long communityId) {
		List<Event> modelList = eventDao.findEventsByCommunityId(communityId);
		List<EventSO> soList = new ArrayList<EventSO>();
		for (Event model : modelList) {
			soList.add(model.convertToServiceObject());
		}
		return soList;
	}
	
	

	
	@Override
	public void updateEvent(EventSO event) {
		eventDao.updateEvent(event.convertToModelObject());
	}
	
	@Override
	public EventSO getEventById(Long eventId) {
		Event model = eventDao.findEventById(eventId);
		if(model != null)
			return model.convertToServiceObject();
		return null;
	}
	
	@Override
	public List<EventSO> getEventsByUser(UserSO user) {
		List<Event> modelList = eventDao.findEventsByUser(user.convertToModelObject());
		List<EventSO> soList = new ArrayList<EventSO>();
		for (Event model : modelList) {
			soList.add(model.convertToServiceObject());
		}
		return soList;
	}
	/**
	 * Saves the event post with event id, user id and post.
	 * @param eventId
	 * @param userId
	 * @param post
	 */
	@Override
	public EventPostSO saveEventPost(Long eventId,Long userId, String post) {
		Event event = eventDao.findEventById(eventId);
		User user = userDao.findUserById(userId);
		EventPost eventPost = new EventPost();
		eventPost.setEvent(event);
		eventPost.setContext(post);
		eventPost.setUser(user);
		
		EventPost model = eventDao.saveEventPost(eventPost);
		
		if(model != null) {
			return model.convertToServiceObject();
		}
		return null;
	}

	@Override
	public EventAttenderSO getEventAttenderByEventIdAndUserId(Long eventId,	Long userId) {
		EventAttender model = eventDao.findEventAttenderByEventIdAndUserId(eventId, userId);
		if(model != null)
			return model.convertToServiceObject();
		return null;
	}
	/**
	 * Saves the event attenders with event id and user id
	 * @param eventId 
	 * @param userId
	 */
	@Override
	public EventAttenderSO saveEventAttender(Long eventId, Long userId) {
		EventAttender eventAttender = new EventAttender();
		User user = userDao.findUserById(userId);
		Event event = eventDao.findEventById(eventId);
		if(user != null && event != null) {
			eventAttender.setEvent(event);
			eventAttender.setUser(user);
			eventAttender = eventDao.saveEventAttender(eventAttender);
			if(eventAttender != null)
				return eventAttender.convertToServiceObject();
		}
		return null;
	}
	
	@Override
	public void deleteEventAttender(Long eventId, Long userId){
		EventAttender eventAttender = eventDao.findEventAttenderByEventIdAndUserId(eventId, userId);
		if(eventAttender != null) {
			eventDao.deleteEventAttender(eventAttender);
		}
	}

	@Override
	public EventSO getModeratedEventByEventIdAndUserId(Long eventId, Long userId) {
		Event model = eventDao.findModeratedEventByEventIdAndUserId(eventId, userId);
		if(model != null) {
			return model.convertToServiceObject();
		}
		return null;
	}
	
	@Override
	public List<UserSO> getModeratorsByEventId(Long eventId) {
		List<User> modelList = eventDao.findModeratorsByEventId(eventId);
		List<UserSO> soList = new ArrayList<UserSO>();
		for (User model : modelList) {
			soList.add(model.convertToServiceObject());
		}
		return soList;
	}
}
